import time
import logging
import threading
import os
from pathlib import Path
from Detector import Detector
import cv2
import requests

from DectionData import DetectionData
from MyTrackerB import MyTracker
from ConfigClass import ConfigClass


class VideoAnalysis:
    def __init__(self, con_fig, detector_):
        self.config = con_fig
        self.detector = detector_
        self.myTrackerList = []
        self.ptCurrentXList = []
        # --------------------------------------------------
        # 创建一个log,用当日的日期写入日志文件
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.INFO)
        logfileName = time.strftime("%Y%m%d", time.localtime())
        logfileName = logfileName + "_analysis_log.txt"
        fh = logging.FileHandler(logfileName, mode='w')
        fh.setFormatter(logging.Formatter("[%(asctime)s]:%(levelname)s:%(message)s"))
        self.logger.addHandler(fh)
        # -------------------- 消息队列------------------------------
        self.MsgList = []
        # -------------------- 检测队列------------------------------
        self.sendMsgThread = threading.Thread(target=self.sendMsg2Server)  # 新建发送消息的线程
        # 定义所有的保存路径
        self.indexJpg = 0
        timestr = time.strftime("%Y%m%d", time.localtime())
        self.dirStr = "./img/" + timestr + "/"
        my_path = Path(self.dirStr)
        if not my_path.exists():
            os.makedirs(self.dirStr)
        self.backup_ID = MyTracker.trackerID - 1

    def sendMsg2Server(self):
        while True:
            try:
                if len(self.MsgList) > 0:
                    # 设置秒数超时，仅对于连接有效
                    Response = requests.get(self.MsgList[0], timeout=self.config.timeout)
                    self.logger.info("url={0}".format(self.MsgList[0]))
                    if Response.status_code != 200:
                        self.logger.info("服务器链接异常")
                    else:
                        # 得到服务器的回应
                        # print(Response.content)
                        del self.MsgList[0]
                else:
                    # sleep 1 seconds
                    time.sleep(1)
            except Exception as e:
                if len(str(e)) != 0 and str(e).isspace() is not True:
                    errorMsg = "sendMsg2Server error={0}".format(e)
                    self.logger.info(errorMsg)

    def addCurrentPointX(self, x1, y1, x2, y2):
        if len(self.ptCurrentXList) == 0:
            self.ptCurrentXList.append([x1, y1, x2, y2])
            return
        for xTemp in self.ptCurrentXList:
            # area = Tools.IntersectionArea(xTemp[0], xTemp[1], xTemp[2], xTemp[3],
            #                               x1, y1, x2, y2)
            x1_avg = (xTemp[0] + xTemp[2]) / 2
            y1_avg = (xTemp[1] + xTemp[3]) / 2
            x2_avg = (x1 + x2) / 2
            y2_avg = (y1 + y2) / 2
            if abs(x1_avg - x2_avg) > self.config.distanceInSamePic or \
                    abs(y1_avg - y2_avg) > self.config.distanceInSamePic:
                self.ptCurrentXList.append([x1, y1, x2, y2])

    def annotate_objects(self, image, results, input_width, input_height):
        currentDetectionList = []
        self.ptCurrentXList.clear()
        # 根据方向的不同，需要花不同的分界线
        if self.config.direct == 1:
            # 18的界限
            cv2.line(image, (MyTracker.min_widthX, 0), (MyTracker.min_widthX, 200), (0, 0, 255), 2)
            cv2.line(image, (MyTracker.max_widthX - self.config.widthStep, 0),
                     (MyTracker.max_widthX - self.config.widthStep, 200), (0, 0, 255), 2)

        else:
            # 19的界限
            cv2.line(image, (MyTracker.min_widthX + self.config.widthStep, 0),
                     (MyTracker.min_widthX + self.config.widthStep, 200), (0, 0, 255), 2)
            cv2.line(image, (MyTracker.max_widthX, 0), (MyTracker.max_widthX, 200), (0, 0, 255), 2)

        for obj in results:
            ymin, xmin, ymax, xmax = obj['bounding_box']
            xmin = int(xmin * input_width)
            xmax = int(xmax * input_width)
            ymin = int(ymin * input_height)
            ymax = int(ymax * input_height)
            h = ymax - ymin
            w = xmax - xmin

            cx = (xmax + xmin) / 2
            # 区别18 和  19
            if self.config.direct == 1:
                # 18 为1
                if MyTracker.min_widthX < cx < MyTracker.max_widthX - self.config.widthStep:
                    cv2.rectangle(image, (xmin, ymin),
                                  (xmax, ymax), (255, 255, 0), 1)
                    # 根据方向，取得不同的h和w,在ini文件种配置
                    if self.config.rect_min_h < h < self.config.rect_max_h \
                            and self.config.rect_min_w < w < self.config.rect_max_w \
                            and w / h < 2.1:
                        self.addCurrentPointX(xmin, ymin, xmax, ymax)

            else:
                # 19 为0
                if MyTracker.min_widthX + self.config.widthStep < cx < MyTracker.max_widthX:
                    cv2.rectangle(image, (xmin, ymin),
                                  (xmax, ymax), (255, 0, 0), 1)
                    # 根据方向，取得不同的h和w,在ini文件种配置
                    if self.config.rect_min_h < h < self.config.rect_max_h \
                            and self.config.rect_min_w < w < self.config.rect_max_w \
                            and w / h < 2.1:
                        self.addCurrentPointX(xmin, ymin, xmax, ymax)

        for k in self.ptCurrentXList:
            current_detection = DetectionData(k[0], k[1], k[2], k[3])
            currentDetectionList.append(current_detection)

        tracklist = MyTracker.trackID(currentDetectionList)

        for i in tracklist:
            print("currentID={0}".format(i.currentID))
            if i.currentID == -1 or i.currentID == -2:
                continue

            cv2.rectangle(image, (i.x1, i.y1),
                          (i.x2, i.y2), (0, 0, 255), 1)
            cv2.putText(image, str(i.currentID),
                        (i.x1, i.y1 - 1), cv2.FONT_HERSHEY_SIMPLEX, 1,
                        [0, 0, 255], 2)

        return image

    def analysisRun(self):

        while True:
            try:
                str_jpg = self.dirStr + "{:0>9d}.jpg"
                str_jpg = str_jpg.format(self.indexJpg)
                if os.path.exists(str_jpg) is True:
                    frame_read = cv2.imread(str_jpg)
                    frame_read_320 = cv2.resize(frame_read,
                                                (320,
                                                 320),
                                                interpolation=cv2.INTER_LINEAR)
                    frame_read_320_rgb = cv2.cvtColor(frame_read_320, cv2.COLOR_BGR2RGB)
                    frame_read_320_rgb = frame_read_320_rgb / 128 - 1
                    results = self.detector.detect_objects(frame_read_320_rgb)
                    h = self.config.cut_bottom - self.config.cut_top
                    w = self.config.cut_right - self.config.cut_left
                    imgResult = self.annotate_objects(frame_read, results, w, h)
                    cv2.putText(imgResult, str(self.indexJpg),
                                (0, 0), cv2.FONT_HERSHEY_SIMPLEX, 1,
                                [255, 255, 255], 2)
                    if self.config.showVideo == 1:
                        cv2.imshow("BBBB", imgResult)
                        cv2.waitKey(1)
                    if self.backup_ID != (MyTracker.trackerID - 1):
                        self.logger.info("sum={0}".format(MyTracker.trackerID - 1))
                        self.backup_ID = MyTracker.trackerID - 1
                        url = self.config.sumUrl + "?videoID=" + str(self.config.videoAID) + "&rectID=1"
                        self.MsgList.append(url)
                    self.indexJpg = 1 + self.indexJpg
                else:
                    cv2.waitKey(5000)
            except Exception as e:
                if len(str(e)) != 0 and str(e).isspace() is not True:
                    errorMsg = "analysisRun error={0}".format(e)
                    self.logger.info(errorMsg)


if __name__ == '__main__':
    config = ConfigClass()

    MyTracker.max_widthX = config.max_widthX
    MyTracker.min_widthX = config.min_widthX
    MyTracker.areaThreshold = config.areaThreshold
    MyTracker.myTrackerList = []
    MyTracker.xStep = config.xStep
    MyTracker.yStep = 0
    MyTracker.direct = config.direct
    MyTracker.widthStep = config.widthStep

    detector = Detector(config.tfFilePath, config.confidenceThreshold)
    video_analysis = VideoAnalysis(config, detector)
    # 启动获取照片主线程
    video_analysis.analysisRun()
